package com.cskaoyan.controller.wx;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.common.BaseRespVo;
import com.cskaoyan.bean.common.User;
import com.cskaoyan.config.realm.MarketToken;
import com.cskaoyan.mapper.MarketUserMapper;
import com.cskaoyan.service.admin.CouponService;
import com.cskaoyan.service.admin.UserService;
import com.cskaoyan.service.wx.CaptchaManagerService;
import com.cskaoyan.service.wx.WxUserService;
import com.cskaoyan.utils.AesUtil;
import com.cskaoyan.utils.CharUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ClassName AuthController
 * @Description TODO
 * @Author by Lester
 * @Date 2022/11/22 14:26
 * @Version 1.0
 */
@RestController
@RequestMapping("wx/auth")
public class WxAuthController {

    @Autowired
    MarketUserMapper userMapper;

    @Autowired
    UserService userService;

    @Autowired
    WxUserService wxUserService;

    @Autowired
    CouponService couponService;

    // 登录
    @PostMapping("login")
    public BaseRespVo<LoginWxUserInfo> loginWx(@RequestBody Map map) throws Exception {
        String username = (String) map.get("username");
        String password = (String) map.get("password");

        // 将加密后的密码与数据库中的做对比
        String encryptPassword = AesUtil.encryptPwd(password);

        Subject subject = SecurityUtils.getSubject();
        MarketToken authenticationToken = new MarketToken(username, encryptPassword, "wx");

        try {
            // realm.doGetAuthenticationInfo
            subject.login(authenticationToken);
        } catch (AuthenticationException e) {
            e.printStackTrace();
            return BaseRespVo.erroPassword();
        }

        Session session = subject.getSession();

        MarketUserExample example = new MarketUserExample();
        MarketUserExample.Criteria criteria = example.createCriteria();
        criteria.andUsernameEqualTo(username);
        List<MarketUser> list = userMapper.selectByExample(example);
        for (MarketUser user : list) {
            session.setAttribute("username", user);
            // 更新最后一次登录时间
            user.setLastLoginTime(LocalDateTime.now());
            userMapper.updateByPrimaryKey(user);
        }

        LoginWxUserInfo loginWxUserInfo = new LoginWxUserInfo();
        UserInfo userInfo = new UserInfo();
        MarketUser userSession = (MarketUser) session.getAttribute("username");
        userInfo.setAvatarUrl(userSession.getAvatar());
        userInfo.setNickName(userSession.getNickname());
        loginWxUserInfo.setUserInfo(userInfo);
        loginWxUserInfo.setToken((String) session.getId());

        return BaseRespVo.ok(loginWxUserInfo);
    }

    @PostMapping("logout")
    public BaseRespVo logout() {

        return BaseRespVo.ok();
    }

    // TODO 注册
    // 请求：{"username":"user567","password":"user567","mobile":"15516100921","code":"508081","wxCode":"003tk80w3B23DZ2ayc3w3H0CUn0tk80D"}
    // 响应：{"errno":0,"data":{"userInfo":{"nickName":"user567","avatarUrl":"https://yanxuan.nosdn.127.net/80841d741d7fa3073e0ae27bf487339f.jpg?imageView&quality=90&thumbnail=64x64"},"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ0aGlzIGlzIG1hcmtldCB0b2tlbiIsImF1ZCI6Ik1JTklBUFAiLCJpc3MiOiJNQVJLRVQiLCJleHAiOjE2NjkxNzYyNzIsInVzZXJJZCI6NywiaWF0IjoxNjY5MTY5MDcyfQ.MacuPLX2_xT3r-ONIqMIT9h5BBZ3M5LrEGkWXeCi7x0"},"errmsg":"成功"}
    @PostMapping("register")
    public BaseRespVo register(@RequestBody Map map) throws Exception {
        String username = (String) map.get("username");
        String password = (String) map.get("password");
        String mobile = (String) map.get("mobile");
        String code = (String) map.get("code");
        String wxCode = (String) map.get("wxCode");
        // wxCode = "the code is a mock one";
        List<MarketUser> userList = userService.queryUserByUsername(username);
        if (userList.size() > 0) {
            // 用户名已注册
            return BaseRespVo.repetitionUserName();
        }
        userList = userService.queryUserByMobile(mobile);
        if (userList.size() > 0) {
            // 手机号已注册
            return BaseRespVo.repetitionMobile();
        }
        // 判断验证码是否正确
        String captcha = CaptchaManagerService.getCachedCaptcha(mobile);
        if (captcha == null || captcha.isEmpty() || !captcha.equals(code)) {
            // 验证码错误
            return BaseRespVo.errorCaptcha();
        }

        // 密码加密
        // 加密后的密码
        String encryptPassword = AesUtil.encryptPwd(password);

        MarketUser user = new MarketUser();
        user.setUsername(username);
        user.setPassword(encryptPassword);
        user.setMobile(mobile);
        user.setAvatar("https://imgsa.baidu.com/forum/w%3D580/sign=35447968b7014a90813e46b599763971/5dd57b899e510fb32477b14dd733c895d0430c92.jpg");
        user.setNickname(username);
        user.setGender((byte) 0);
        user.setUserLevel((byte) 0);
        user.setStatus((byte) 0);
        user.setLastLoginTime(LocalDateTime.now());
        userService.add(user);

        // 遍历优惠券，查找新人注册优惠券进行发放
        couponService.ProvideCoupon(user.getId());

        // userInfo
        UserInfo userInfo = new UserInfo();
        userInfo.setNickName(username);
        userInfo.setAvatarUrl(user.getAvatar());

        // token
        MarketToken wxToken = new MarketToken(username, encryptPassword, "wx");
        //=================================================================================
        Subject subject = SecurityUtils.getSubject();
        try {
            subject.login(wxToken);
        } catch (AuthenticationException e) {
            e.printStackTrace();
        }

        Session session = subject.getSession();
        //=================================================================================
        UserInfoBean userInfoBean = new UserInfoBean();

        //准备返回用户信息
        LoginData loginUserData = new LoginData();
        userInfoBean.setAvatarUrl(user.getAvatar());
        userInfoBean.setNickName(user.getUsername());
        loginUserData.setUserInfo(userInfoBean);
        loginUserData.setToken((String) session.getId());
        loginUserData.setToken(wxCode);
        return BaseRespVo.ok(loginUserData);
    }

    // TODO 请求发送验证码
    // 请求：{"mobile":"15516100921"}
    // 响应：{"errno":0,"errmsg":"成功"}
    @PostMapping("regCaptcha")
    public BaseRespVo registerCaptcha(@RequestBody Map map) {
        String mobile = (String) map.get("mobile");
        // 手机号码必须为11位
        if (mobile.length() != 11) {
            return BaseRespVo.invalidParameter();
        }
        // 生成6位纯数字验证码
        String captcha = CharUtil.getRandomNum(6);

        // 发送验证码
        wxUserService.senSms(mobile, captcha);

        // 限制一分钟内只能发送一次验证码
        boolean time = CaptchaManagerService.addToCache(mobile, captcha);
        if (!time) {
            return BaseRespVo.captchaTime();
        }

        return BaseRespVo.ok();
    }

    // TODO 忘记密码 → 修改
    // 请求：{"mobile":"15935119202","code":"940622","password":"123456"}
    // 响应：{"errno":0,"errmsg":"成功"}
    @PostMapping("/reset")
    public BaseRespVo forgetPassword(@RequestBody Map map) throws Exception {
        String mobile = (String) map.get("mobile");
        String code = (String) map.get("code");
        String password = (String) map.get("password");
        // 前端帮忙实现了，这里不需要判断，包括判空操作
        /*if (mobile.length()!=11){
            return BaseRespVo.invalidParameter();
        }*/
        // 检验验证码是否正确
        String cacheCode = CaptchaManagerService.getCachedCaptcha(mobile);
        if (cacheCode == null || cacheCode.isEmpty() || !cacheCode.equals(code)) {
            // 验证码错误
            return BaseRespVo.errorCaptcha();
        }
        // 账号未注册情况下不允许修改密码，但是前端没实现此情况的接口
        List<MarketUser> userList = userService.queryUserByMobile(mobile);
        MarketUser user = null;
        if (userList.size() > 1) {
            // 手机号不唯一
            return BaseRespVo.noSingleMobile();
        } else if (userList.size() == 0) {
            // 手机号未注册
            return BaseRespVo.unregisteredMobile();
        } else {
            user = userList.get(0);
        }
        String encryptPassword = AesUtil.encryptPwd(password);
        user.setPassword(encryptPassword);
        //修改密码
        if (wxUserService.passwordCheck(user) == 0) {
            // 更新密码失效
            return BaseRespVo.invalidData();
        }
        return BaseRespVo.ok();
    }

    /**
     * 张家齐
     */
    @PostMapping("/noAuth")
    public BaseRespVo noAuth() {
        return BaseRespVo.error(501, "请登录");
    }
}
